package com.xiaomaoguai.hessian.config;

import com.xiaomaoguai.hessian.annotation.HessianPath;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.remoting.caucho.HessianServiceExporter;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Map;
import java.util.Set;

/**
 * @fileName: HessianServerAutoConfigure.java
 * @author: WeiHui
 * @date: 2018/2/3 13:32
 * @version: v1.0.0
 * @since JDK 1.8
 */
@Slf4j
@EnableConfigurationProperties(HessianServerProperties.class)
public class HessianServerAutoConfigure {

	@Resource
	private GenericApplicationContext applicationContext;

	@Resource
	private HessianServerProperties hessianServerProperties;

	@PostConstruct
	public void registerHessianServerBean() {
		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
		Map<String, Object> beans = beanFactory.getBeansWithAnnotation(HessianPath.class);
		Set<Map.Entry<String, Object>> entries = beans.entrySet();
		for (Map.Entry<String, Object> entry : entries) {
			String refBean = entry.getKey();
			Object value = entry.getValue();
			Class<?> clazz = value.getClass();
			Class<?> interfaces = clazz.getInterfaces()[0];
			String hessianUrl = registerBeanDefinition(beanFactory, refBean, interfaces);
			log.info("=====> Register hessian server bean: \n {} with URI : {}", clazz, hessianUrl);
		}
	}

	/**
	 * 创建bean并且放入springBean工厂，取代xml的繁琐配置
	 *
	 * @param beanFactory               bean工厂
	 * @param hessianServiceImplRefBean serviceImpl--bean 的名称
	 * @param hessianServiceInterface   service的全类名
	 */
	private String registerBeanDefinition(DefaultListableBeanFactory beanFactory, String hessianServiceImplRefBean, Class<?> hessianServiceInterface) {
		// 通过BeanDefinitionBuilder创建bean定义
		BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(HessianServiceExporter.class);
		// 设置属性userAcctDAO,此属性引用已经定义的bean:userAcctDAO
		beanDefinitionBuilder.addPropertyReference("service", hessianServiceImplRefBean);
		beanDefinitionBuilder.addPropertyValue("serviceInterface", hessianServiceInterface);
		// 注册bean
		String hessianServerUrl = "/" + hessianServiceInterface.getSimpleName() + hessianServerProperties.getSuffix();
		beanFactory.registerBeanDefinition(hessianServerUrl, beanDefinitionBuilder.getRawBeanDefinition());
		return hessianServerUrl;
	}
}
